package com.net.xpay.admin.controller.admin;

import com.alipay.api.AlipayApiException;
import com.alipay.api.response.AlipayFundAccountbookQueryResponse;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.net.common.exception.BusinessException;
import com.net.common.model.ResultData;
import com.net.common.model.ResultList;
import com.net.xpay.admin.po.UpdateSafePayBookAccountPo;
import com.net.xpay.alipay.safePay.PoseidonSafePayAlipayClient;
import com.net.xpay.common.domain.UserShard;
import com.net.xpay.common.manager.UserShardManager;
import com.net.xpay.core.constant.PoseidonErrorCode;
import com.net.xpay.core.domain.safePay.SafePayBookAccount;
import com.net.xpay.core.enums.SafePayBookAccountSignStatus;
import com.net.xpay.core.manager.safePay.SafePayBookAccountManager;
import com.net.xpay.core.model.SafePayBookAccountSearchModel;
import com.net.shard.ShardDataSource;
import com.net.shard.ShardDataSourceConfigurer;
import com.net.shard.ShardUtil;
import com.net.shard.domain.ShardConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.sql.DataSource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;

/**

 */
@RestController
@Slf4j
@RequestMapping("/admin/safe-pay-book-account")
@Api(tags = "运营/支付宝账号", description = "运营 支付宝账号 net")
public class AdminSafePayBookAccountController {

    @Autowired
    private SafePayBookAccountManager safePayBookAccountManager;

    @Autowired
    private UserShardManager userShardManager;

    @Autowired
    @Qualifier("shardDataSource")
    private DataSource shardDataSource;

    @Autowired
    private PoseidonSafePayAlipayClient xpaySafePayAlipayClient;


    /**
     * 列表
     */
    @ApiOperation("列表")
    @PostMapping("/list")
    @PreAuthorize("hasAnyRole('ADMIN', 'safe-pay-book-account::list')")
    public ResultList<SafePayBookAccount> list(@RequestBody SafePayBookAccountSearchModel searchModel)  {
        Preconditions.checkArgument(searchModel != null && searchModel.getUserId() != null);

        UserShard userShard = userShardManager.getById(searchModel.getUserId());
        try {
            ShardUtil.setShardContext(userShard.getShardId());
            List<SafePayBookAccount> records = safePayBookAccountManager.list(searchModel);

            return new ResultList<>(records);
        } finally {
            ShardUtil.cleanShardContext();
        }
    }

    /**
     * 查询记账本
     */
    @ApiOperation("查询记账本")
    @PostMapping("/query-by-book-id")
    @PreAuthorize("hasAnyRole('ADMIN')")
    public ResultData<SafePayBookAccount> queryByBookId(String bookId)  {
        if (Strings.isNullOrEmpty(bookId)) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "请输入记账本ID");
        }

        //查询所有的库
        ShardDataSourceConfigurer shardDataSourceConfigurer = ((ShardDataSource) shardDataSource).getShardDataSourceConfigurer();
        Map<Long, ShardConfig> shardConfigMap = shardDataSourceConfigurer.getShardConfigMap();
        //切库
        for (Long shardId : shardConfigMap.keySet()) {
            try {
                ShardUtil.setShardContext(shardId);
                SafePayBookAccount account = safePayBookAccountManager.getByBookId(bookId);
                if (account != null) {
                    return new ResultData<>(account);
                }

            } finally {
                ShardUtil.cleanShardContext();
            }

        }

        return new ResultData<>();
    }



    /**
     * 跟新
     */
    @ApiOperation("跟新")
    @PostMapping("/update")
    @PreAuthorize("hasAnyRole('ADMIN', 'safe-pay-book-account::update')")
    public ResultData<Boolean> updateAccount(@RequestBody UpdateSafePayBookAccountPo updatePo)  {
        Preconditions.checkArgument(updatePo != null && updatePo.getUserId() != null);
        if (Strings.isNullOrEmpty(updatePo.getAlipayNickName())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "请输入企业支付宝");
        }


        UserShard userShard = userShardManager.getById(updatePo.getUserId());
        try {
            ShardUtil.setShardContext(userShard.getShardId());
            SafePayBookAccount account = safePayBookAccountManager.findByAlipayNickName(updatePo.getUserId(), updatePo.getAlipayNickName());
            if (account == null) {
                throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "支付宝账号不存在");
            }
            account.setBatchEnsure(updatePo.getBatchEnsure());
            safePayBookAccountManager.updateByPrimaryKeyWithVersion(account);
            return new ResultData<>(true);
        } finally {
            ShardUtil.cleanShardContext();
        }
    }

    /**
     * 查询已签约安全发余额
     */
    @ApiOperation("查询已签约安全发余额")
    @PostMapping("/query-safe-pay-book-total-balance")
    public ResultData<String> querySafePayBookTotalBalance()  {
        //查询所有的库
        ShardDataSourceConfigurer shardDataSourceConfigurer = ((ShardDataSource) shardDataSource).getShardDataSourceConfigurer();
        Map<Long, ShardConfig> shardConfigMap = shardDataSourceConfigurer.getShardConfigMap();
        Preconditions.checkArgument(CollectionUtils.isNotEmpty(shardConfigMap.keySet()));
        //切库
        BigDecimal allBalance = new BigDecimal("0");
        for (Long shardId : shardConfigMap.keySet()) {
            try {
                ShardUtil.setShardContext(shardId);
                SafePayBookAccountSearchModel searchModel = new SafePayBookAccountSearchModel();
                searchModel.setSignStatus(SafePayBookAccountSignStatus.NORMAL);
                List<SafePayBookAccount> records = safePayBookAccountManager.list(searchModel);
                for (SafePayBookAccount record : records) {
                    AlipayFundAccountbookQueryResponse resp;
                    try {
                        resp = xpaySafePayAlipayClient.queryAlipayFundAccountbook(record.getBookId(), record.getAgreementNo());
                        if (resp.isSuccess()) {
                            allBalance = allBalance.add(new BigDecimal(resp.getAvailableAmount()));
                        } else {
                            log.warn("query account failed|account={}|userId={}|errorCode={}|errMsg={}", record.getAlipayNickName(), record.getUserId(), resp.getSubCode(), resp.getSubMsg());
                        }
                    } catch (AlipayApiException e) {
                        log.warn("query account error|account={}|userId={}", record.getAlipayNickName(), record.getUserId(), e);
                        throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "查询繁忙：请重试或联系客服");
                    }

                }

            } finally {
                ShardUtil.cleanShardContext();
            }

        }



        return new ResultData<>(allBalance.setScale(2, RoundingMode.HALF_UP).toString());
    }

}
